# -*- coding:cp437 -*-
# WARNIG : encodage pour Console DOS sous Windows uniquement !!!

# Insert Special
# based on : InsertNFO/Dolores
# (c) www.ctrl-pomme-reset.fr
# version 0.51 (30.09.2014)


import sys
import struct
import glob
import os.path

# interleaving !
#SectorList = [0,7,14,6,13,5,12,4,11,3,10,2,9,1,8,15]   #1:1 => trŠs trŠs lent (1min49)
#SectorList = [0,14,13,12,11,10,9,8,7,6,5,4,3,2,1,15]   #2:1 => trŠs trŠs lent (1min55)
#SectorList = [0,6,12,3,9,15,14,5,11,2,8,7,13,4,10,1]   #3:1 => ultra lent (2m01)
#SectorList = [0,13,11,9,7,5,3,1,14,12,10,8,6,4,2,15]   #4:1 => trŠs lent /d‚cousu (1min55) 
#SectorList = [0,5,10,15,13,3,8,6,11,1,14,4,9,7,12,2]   #5:1 => trŠs lent - "d‚cousu"
#SectorList = [0,12,9,14,11,8,13,10,7,4,1,6,3,15,5,2]   #6:1 => ultra rapide en montant - bloque en descendant
#SectorList = [0,4,8,5,9,6,10,7,11,15,12,1,13,2,14,3]   #7:1 => bloque en montant - nickel en descendant !
#SectorList = [0,11,15,4,8,12,1,5,9,13,2,6,10,14,3,7]   #8:1 => preque bon en montant - bloque en descendant
#SectorList = [0,3,14,2,13,1,12,15,11,7,10,6,9,5,8,4]   #9:1 => bloque en montant - nickel en descendant !
#SectorList = [0,10,13,8,11,14,9,12,7,2,5,15,3,6,1,4]   #10:1 => ok en montant - bloque en descendant
#SectorList = [0,2,12,7,9,4,14,1,11,6,8,3,13,15,10,5]   #11:1 => bloque en montant - OK en descendant
#SectorList = [0,9,11,13,7,1,3,5,14,8,10,12,6,15,2,4]   #12:1 => ok en montant - bloque en descendant
#SectorList = [0,1,10,4,13,7,8,2,11,5,14,15,9,3,12,6]   #13:1 => OK montant/descendant - lent (1min24)
#SectorList = [0,8,9,10,11,12,13,14,15,1,2,3,4,5,6,7]   #14:1 => OK montant/descendant - lent (1min30)
#SectorList = [0,15,8,1,9,2,10,3,11,4,12,5,13,6,14,7]   #15:1 => trŠs lent (1min36)

#Custom
#SectorList = [0,12,2,14,3,15,13,1,11,7,10,6,9,5,8,4]   #6:1(mod)/9:1 - CUSTOM 2 => bloque/d‚cousu en montant

SectorList = [0,3,13,15,2,14,1,12,11,7,10,6,9,5,8,4]    #10:1(mod)/#9:1 (1min05) - CUSTOM 1 => OK


    
# routines

def WriteFRA(modDSK, nameBinary1, nameBinary2, track, sector): 
    fbin1 = open(nameBinary1,"rb")
    load1 = fbin1.read()                            # lecture du fichier binaire1
    lenBin1 = len(load1)                            # on r‚cupŠre la taille du binaire1
    modBin1 = bytearray(load1)                      # cr‚ation array avec le bin1   

    fbin2 = open(nameBinary2,"rb")
    load2 = fbin2.read()                            # lecture du fichier binaire2
    lenBin2 = len(load2)                            # on r‚cupŠre la taille du binaire2
    modBin2 = bytearray(load2)                      # cr‚ation array avec le bin2

    s = SectorList[sector]
    offset = track*0x1000+s*0x100              # calcul offset dans le fichier DSK pour l'‚criture
                                                    # correspondant … track/sector
    
    j = 0
    k = 0
    while j<lenBin1:
        modifiedDSK[offset+k] = modBin1[j]
        j +=1
        k +=1

    j = 0                                           # nouvelle boucle pour deuxiŠme bin

    while j<lenBin2:
        modifiedDSK[offset+k] = modBin2[j]
        j +=1
        k +=1
        
    modifiedDSK[offset+k] = 0                       # octet de fin de d‚compression : 00
    k +=1                                           # calcul k final pour affichage
    
    print 'Injection de {} et {} ({} octets)'.format(nameBinary1,nameBinary2,k),
    print "T{:02X}/S{:02X}".format(track,s)
    
    # fin - nettoyage / fermeture fichier
    fbin1.close()                       # fermeture fichier binaire1
    fbin2.close()                       # fermeture fichier binaire2

    return


if __name__ == '__main__':

    print
    print("Insert Special v0.50 - 2014")
    print

    if len(sys.argv) < 4:
        nameDSK = raw_input("Nom du de l'image disk : ")
        trackd = int(raw_input("Piste de d‚part (Hexa) : "),16)
        sectord = int(raw_input("Secteur de d‚part (Hexa) : "),16)
    else:    
        nameDSK = sys.argv[1]
        trackd = int(sys.argv[2],16)
        sectord = int(sys.argv[3],16)

    fDSK = open(nameDSK,"rb+")                  # ouverture fichier DSK (lecture + modification)
    record = fDSK.read()                        # lecture complŠte
    if len(record) != 143360:                   # v‚rification taille standard d'un fichier DSK
        print ("erreur avec le fichier DSK")
    else :
        bufDSK = struct.Struct("<143360B")      # structure fichier DSK (143360 x 1 byte)
        outDSK = bufDSK.unpack(record)          # on unpack le fichier DSK vers la structure d‚finie
        modifiedDSK = bytearray(outDSK)         # on cr‚e une bytearray … partir du contenu pour pouvoir la modifier

    track = trackd
    sector = sectord
    
    l = glob.glob('*.fra')                      # liste tous les fichiers .fra du rep
    # boucle principale
    sens = 0                                    # sens ascendant pour commencer !
    for i in range(0,len(l),2):                                     # boucle traitement liste
        (filepath1,filename1)=os.path.split(l[i])                   # d‚coupe path+filename
        (filepath2,filename2)=os.path.split(l[i+1]) 
        WriteFRA(modifiedDSK,filename1,filename2,track,sector)
        # calcul prochain track/sector
        if sens == 0:                           # sens ascendant !
            sector +=1                          # secteur suivant
            if sector>0x7:                      # en bout de piste (7 pour le sens ascendant) ?
                sector = 0                      # secteur remis … 0
                track +=1                       # ... et piste suivante
                if track > 0x22:                # bout du disk ? on redescent !
                    sens = 1                    # sens descendant
                    track = 0x22                # on repart de la piste $22
                    sector = 8                  # ... secteur 8
                    continue                    # prochaine it‚ration boucle !

        if sens == 1:                           # sens descendant
            sector +=1                          # secteur suivant
            if sector>0x0F:                     # en bout de piste (0F pour le sens descendant) ?
                sector = 8                      # secteur remis … 8
                track -=1                       # ... et piste pr‚c‚dente
                if track < trackd:              # t < track de d‚part ? on a fini quoiqu'il arrive !
                    break                       # on sort de la boucle for

    record = bufDSK.pack(*modifiedDSK)          # on repack la liste modif‚e vers la structure
    fDSK.seek(0)			        # on remet … zero le file pointer (pour tout r‚‚crire)
    fDSK.write(record)                   	# ecriture vers fichier sortie de la structure
    print
    print "-> fichier",nameDSK,"modifi‚ et sauv‚"

    fDSK.close()                                # fermeture fichier DSK
